/**
 * Created by Administrator on 2017/1/15.
 */

var config = require('./config');

var MJ = require('../MJ/MJ');
var MJRoom = require('../MJ/room').MJRoom;

var Const = require('./const');
var SubCode = require('../subCode');

var MJSettlementStatus = {
    'NONE': 0,  // 还未结算
    'WAIT': 1,  // 等待结算
    'DONE': 2,  // 结算结算
}

exports.HFMJRoom = MJRoom.extend({

    baoCard: 0,                 //宝牌
    _shaiziN: 0,                //骰子n
    yNum1:0,
    yNum2:0,
    yNum3:0,
    yNum4:0,
    _shaiziM: 0,                //骰子m
    yaoshaizi: 0,              //摇骰子次数
    _cfxz:false,
    _firstturns:{},
    _playcard:0,
    SecondPlayer: 0,

    init: function(rid, creator, msg) {
        this._super(rid, creator, msg);

        this.baoCard = 0;
        this._shaiziN = 0;
        this._shaiziM = 0;
        this.yaoshaizi = 0;
        this.yNum1 = 0;
        this.yNum2 = 0;
        this.yNum3 = 0;
        this.yNum4 = 0;
        this._cfxz = false;
        this._firstturns = {};
        this._playcard = 0;
        this.SecondPlayer = 0;
    },

    checkInit: function() {
        return this._super();
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getRoomConfig: function() {
        var cfg = this._super();
        cfg.destroyWaitTime = 120;
        return cfg;
    },

    getInfo: function() {
        var info = this._super();

        info.baoCard = this.baoCard;

        return info;
    },

    getRoundInfo: function() {
        var info = this._super();
        return info;
    },

    getReconnectInfo: function(rePlayer) {
        var info = this._super(rePlayer);
        info.baoCard = this.baoCard;
        info.yaoshaizi = this.yaoshaizi;
        info.num1 = this.yNum1;
        info.num2 = this.yNum2;
        info.num3 = this.yNum3;
        info.num4 = this.yNum4;
        info.secondindex = this.SecondPlayer;
        return info;
    },

    onBeforeStartNewRound: function() {
        this._super();
        this.yaoshaizi = 0;
        this._firstturns = {};
        this._playcard = 0;
        this._cfxz = false;
       // this._piaoStatus = Const.PiaoStatus.NONE;

    },

    onAfterStartNewRound: function() {
        this._super();

        //this.preStartPlay();
    },

    preStartPlay: function() {
        this.initPlayersHandCards();
        this.startPlay();
    },

    startPlay: function() {
        var dealer = this.getDealerIndex();

        logger.debug("room=%d sendHangupTask in=HFMJ.startPlay", this.rid());

        this._sendHangupTask(this._startPlay);
    },

    _startPlay: function() {
        this._changeCurPlay(this.getDealerIndex());
        this._doCheckNewCardHangupTask();
    },

    onBeforePlayCard: function(player, msg, card) {
        var code = this._super(player, msg, card);
        if (code) {
            return code;
        }

        /*if(this._curTask == MJ.Task.CHI){
            if(card == player._chiCards[player._chiCards.length - 1].card){
                return SubCode.MJ_PLAY_FAILED;
            }
        }*/

        if (player.isBaoTing() && card != player.getLastCard()) { //天听不能换牌
            return SubCode.MJ_IS_BAOTING;
        }
    },
    onAfterPlayCard: function(player, card, playInfo) {
        this._super(player, card, playInfo);

        var room = this;
        if(card == room.baoCard) {
            player._dabao += 1;
        }
        player._PassPengCard = 0;
        if(this._playcard < 5) {
            if(!this._firstturns[card]){
                this._firstturns[card] = 0;
            }
            this._firstturns[card] += 1;
            this._playcard++;
        }
        if(this._playcard == 4) {
            ExObject.eachKeyNum(this._firstturns, function(c, n) {
                if (n == 4) {
                    room._cfxz =true;
                    room.settlementCurRound(0);
                } else if (n == 3) {
                    if(c == room.baoCard){
                        room._cfxz =true;
                        room.settlementCurRound(0);
                    }
                }
            });
            this._playcard++;
        }
    },

    checkNewCardHangupTask: function() {
        var player = this.getCurPlayer();

        var huIndexs = [];
        var huPattern = player.checkHu();
        if (huPattern != Const.Pattern.NONE) {
            var rules = [];
            if (player.isFirstHand()) {
                if (player.getIndex() == this.getDealerIndex()) {
                    rules.push(Const.ScoreRule.TH);
                }
            } else {
                if (player.isBaoTing()) {
                    rules.push(Const.ScoreRule.BT);
                }
            }
            if (this.getCurGang()) {
                rules.push(Const.ScoreRule.GSH);
            }

            var card = player.getLastCard() || player.getInitLastCard();
            this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), huPattern, rules);
            huIndexs.push(player.getIndex());
        }
        var gangArray = player.checkGang();
        if (gangArray.length > 0) {
            this._hangupTask.addGangTask(player.getIndex(), gangArray);
        }

        huIndexs.forEach(function(eIndex) {
            var ePlayer = this.getPlayerByIndex(eIndex);
            if (ePlayer && ePlayer.isBaoTing()) {
                this._hangupTask.submitTask(eIndex, MJ.Task.HU);
            }
        }.bind(this));
    },

    checkPlayCardHangupTask: function(card) {
        var player = this.getCurPlayer();
        this._checkPlayCardHangupTask(card);
    },
    dealHangupTaskChi: function(task) {
        logger.debug("room=%d onHangupTaskChi args=%j", this.rid(), task);
        var playerIndex = task.playerIndex;
        var fromIndex = task.from;

        var player = this.getPlayerByIndex(playerIndex);
        if (!player.chiCard(task)) {
            return;
        }

        var fromPlayer = this.getPlayerByIndex(fromIndex);
        if (fromPlayer) {
            fromPlayer.setLastPlayCardTask(MJ.Task.CHI);
        }
        var cardInfo = player._chiCards[player._chiCards.length - 1];
        this.broadcastReplay("onPlayerChiCard", {
            playerIndex: playerIndex,
            from: fromIndex,
            card: task.card,
            selectCard: cardInfo.selectCard
        });

        player.setPassHu(false);
        this._changeCurPlay(playerIndex, MJ.Task.CHI);
        this.onAfterChiTask(player, task.card, task);

        this._doCheckCurPlayHangupTask();
    },
    _checkPlayCardHangupTask: function(card) {
        var curPlay = this.getCurPlay();
        var nextIndex = this.getNextIndex(curPlay);

        var curPlayer = this.getCurPlayer();
        if (!curPlayer.getLastCard() || curPlayer.getLastCard() != card) { // 不是打的上次摸的牌，则重新检查听牌
            //var tings = curPlayer.checkTing();
            //curPlayer.setTingCards(tings);
        }

        var huIndexs = [];
        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != curPlay && !ePlayer.isRoundHu()) {
                if (!ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                    var huPattern = ePlayer.checkHuWithCard(card);
                    if (huPattern != Const.Pattern.NONE) {
                        var rules = [];
                        /*if (ePlayer.isBaoTing()) {
                            rules.push(Const.ScoreRule.BT);
                        }*/
                        if (ePlayer.isFirstHand() && ePlayer.getIndex() != this.getDealerIndex()) {
                            rules.push(Const.ScoreRule.DIHU);
                        }

                        if (this.getCurGang() > 0) {
                            rules.push(Const.ScoreRule.GSP);
                        }

                        this._hangupTask.addHuTask(ePlayer.getIndex(), card, curPlay, huPattern, rules);
                        huIndexs.push(eIndex);
                    }
                }

                if (!ePlayer.isBaoTing()) {
                    if (ePlayer.checkPengWithCard(card) && card != ePlayer._PassPengCard) {
                        if(curPlay == this.getNextIndex(eIndex)){
                            ePlayer._PassPengCard = card;
                        }
                        this._hangupTask.addPengTask(eIndex, card, curPlay);
                    }

                    if (ePlayer.checkGangWithCard(card)) {
                        this._hangupTask.addGangTask(eIndex, [{card: card, from: curPlay, gang: MJ.Gang.DIAN}]);
                    }

                    if (eIndex == nextIndex) { // 下家可以吃牌
                        var maxCards = ePlayer.checkChiWithCard(card);
                        if (maxCards) {
                            this._hangupTask.addChiTask(eIndex, card, curPlay, maxCards);
                        }
                    }
                }
            }
        }.bind(this));

        huIndexs.forEach(function(eIndex) {
            var ePlayer = this.getPlayerByIndex(eIndex);
            if (ePlayer && ePlayer.isBaoTing()) {
                this._hangupTask.submitTask(eIndex, MJ.Task.HU);
            }
        }.bind(this));
    },
    onAfterPengTask: function(player, card, pengTask) {

        if(card == this.baoCard) {
            player._dabao += 2;
        }
    },
    onAfterGangTask: function(player, card, gangTask, gangInfo) {
        this._super(player, card, gangTask, gangInfo);
        
        var gang = gangTask.gangArray[0].gang;

        if(gangTask.gangArray[0].card == this.baoCard) {
            if(gang == MJ.Gang.AN){
                player._dabao += 4;
            }else if(gang == MJ.Gang.BA){
                player._dabao += 1;
            }else if(gang == MJ.Gang.DIAN){
                player._dabao += 3;
            }else if(gang == MJ.Gang.ANS){
                player._dabao += 4;
            }
        }
    },
    checkCurPlayHangupTask: function() {
        var player = this.getCurPlayer();
        if (!player.isBaoTing()) {
            var gangArray = player.checkGang();
            if (gangArray.length > 0) {
                this._hangupTask.addGangTask(player.getIndex(), gangArray);
            }
        }
        this.onAfterNewCard();
    },
    checkGangHangupTask: function(playerIndex, gangInfo) {
        var card = gangInfo.card;
        if (gangInfo.type) {
            card = gangInfo.buCard;
        }

        var huIndexs = [];
        this.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != playerIndex && !ePlayer.isRoundHu() && !ePlayer.isPassHu() && ePlayer.getBaoTingPassHuTimes() < 1) {
                var huPattern = ePlayer.checkHuWithCard(card);
                if (huPattern != Const.Pattern.NONE) { // 抢杠
                    var rules = [];
                    rules.push(Const.ScoreRule.QG);

                    if (ePlayer.isBaoTing()) {
                        rules.push(Const.ScoreRule.BT);
                    }

                    this._hangupTask.addHuTask(eIndex, card, playerIndex, huPattern, rules);
                    huIndexs.push(eIndex);
                }
            }
        }.bind(this));
    },

    checkGangTaskQG: function(task, gangInfo) {
        if (gangInfo.type) {
            return task.buCard ? true : false;
        } else {
            return gangInfo.gang == MJ.Gang.BA;
        }
    },

    checkGangNewCard: function(gangInfo) {
        if (gangInfo.type) {
            if (gangInfo.buCard) {
                return true;
            }
            if (gangInfo.type == Const.SpecGang.XI || gangInfo.type == Const.SpecGang.YD || gangInfo.type == Const.SpecGang.JD) {
                return false;
            }
        }

        return true;
    },

    checkHuSettlement: function() {
        return true;
    },

    onSettlementHuTask: function(task) {
        var playerIndex = task.playerIndex;
        var pattern = task.pattern;
        var card = task.card;
        var from = task.from;
        var rules = task.rules;
        var huPlayer = this.getPlayerByIndex(playerIndex);

        var isZM = (playerIndex == from); // 是否是自摸

        var targetsIndex = [];
        var targets = [];
        if (isZM) {
            huPlayer.addRoundItemScores(Const.ScoreRule.ZM, Const.ItemScore[Const.ScoreRule.ZM]);
            huPlayer.setRoundScoreRule(Const.ScoreRule.ZM);
            this.enumPlayers(function(eIndex, ePlayer) {
                if (eIndex != playerIndex && !ePlayer.isRoundHu()) {
                    targetsIndex.push(eIndex);
                    targets.push(ePlayer);
                }
            });
        } else {
            huPlayer.addRoundItemScores(Const.ScoreRule.DH, Const.ItemScore[Const.ScoreRule.DH]);
            huPlayer.setRoundScoreRule(Const.ScoreRule.DH);
            targetsIndex.push(from);
            targets.push(this.getPlayerByIndex(from));
        }


        for (var i = 0; i < rules.length; ++i) {
            var rule = rules[i];
            switch (rule) {
                case Const.ScoreRule.QG:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        if (targetPlayer.getIndex() == this.getCurPlay() && this.getCurGang() > 0) { // 抢杠的被抢玩家一定是当前玩家
                            //targetPlayer.setRoundScoreRule(rule);
                            targetPlayer.cancelLastGangForQG(card);
                        }
                    }
                    break;
                case Const.ScoreRule.GSP:
                    if (!isZM) {
                        var targetPlayer = targets[0];
                        targetPlayer.setLastGangUnscored();
                    }
                    break;
                default:
                    break;
            }
            if(rule == Const.ScoreRule.GSH || rule == Const.ScoreRule.QG || rule == Const.ScoreRule.TH || rule == Const.ScoreRule.DIHU) {
                switch (rule) {
                    case Const.ScoreRule.QG:
                        if (pattern == Const.Pattern.NORMAL) {
                            pattern = Const.Pattern.QIANGGANG;
                        }else if (pattern == Const.Pattern.QZQ) {
                            rule = Const.ScoreRule.QZQQG;
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                            pattern = Const.Pattern.QZQQG;
                        }else if (pattern == Const.Pattern.ONE13) {
                            rule = Const.ScoreRule.ONE13QG;
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                            pattern = Const.Pattern.ONE13QG;
                        } else {
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                        }
                        break;
                    case Const.ScoreRule.GSH:
                        if (pattern == Const.Pattern.PPH) {
                            pattern = Const.Pattern.PPHGSH;
                        } else if (pattern == Const.Pattern.NORMAL) {
                            pattern = Const.Pattern.GANGKAI;
                        } else {
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                        }
                        break;
                    case Const.ScoreRule.TH:
                        if (pattern == Const.Pattern.NORMAL) {
                            pattern = Const.Pattern.TIANHU;
                        }else if (pattern == Const.Pattern.QZQ) {
                            rule = Const.ScoreRule.THQZQ;
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                            pattern = Const.Pattern.THQZQ;
                        }else if (pattern == Const.Pattern.ONE13) {
                            rule = Const.ScoreRule.THONE13;
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                            pattern = Const.Pattern.THONE13;
                        }else{
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                        }
                        break;
                    case Const.ScoreRule.DIHU:
                        if (pattern == Const.Pattern.NORMAL) {
                            pattern = Const.Pattern.DIHU;
                        }else if (pattern == Const.Pattern.QZQ) {
                            rule = Const.ScoreRule.DHQZQ;
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                            pattern = Const.Pattern.DHQZQ;
                        }else if (pattern == Const.Pattern.ONE13) {
                            rule = Const.ScoreRule.DHONE13;
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                            pattern = Const.Pattern.DHONE13;
                        }else{
                            huPlayer.setRoundScoreRule(rule);
                            huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
                        }
                        break;
                    default:
                        break;
                }
            }else {
                huPlayer.setRoundScoreRule(rule);
                huPlayer.addRoundItemScores(rule, Const.ItemScore[rule]);
            }
        }
        var patternScore = Const.PatternScore[pattern];
        var huResult = isZM ? MJ.Result.ZM : MJ.Result.DH;
        huPlayer.setRoundResult(huResult, targetsIndex, card);
        huPlayer.setRoundPattern(pattern, patternScore);

        this.broadcast("onPlayerHu", {
            playerIndex: playerIndex,
            card: card,
            from: from,
        });
    },

    onSettlement: function() {
        this.enumPlayers(function(eIndex, ePlayer) {
            this._settlementPlayerTing(ePlayer);
        }.bind(this));

        this.enumPlayers(function(eIndex, ePlayer) {
            ePlayer.settlementRules();
        }.bind(this));

        this.enumPlayers(function(eIndex, ePlayer) {
            //ePlayer.settlementGangScore();
            ePlayer.settlementBaocardScore();
            ePlayer.settlementPatternScore();
        }.bind(this));

        if(this.isRoundHZ()){
            var playernum = this.getMaxPlayer();
            playernum -= 1;
            var DealerPlayer = this.getDealerIndex();
            var score = playernum * 2;
            if(this._cfxz){
                this.enumPlayers(function(eIndex, ePlayer) {
                    if(eIndex == DealerPlayer){
                        ePlayer.addRoundScore(-score);
                    }else {
                        ePlayer.addRoundScore(2);
                    }
                });
            }else{
                this.enumPlayers(function(eIndex, ePlayer) {
                    if(eIndex == DealerPlayer){
                        ePlayer.addRoundScore(score);
                    }else {
                        ePlayer.addRoundScore(-2);
                    }
                });
            }
        }
    },

    onCurRoundFinished: function() {
        this._super();

        // 计算新的庄家
        if (this.getFirstHuPlayerIndex() == this._dealerIndex) {
            this._dealerLZ++;
        } else {
            this._dealerIndex = this.getNextIndex(this._dealerIndex);
            this._dealerLZ = 1;
        }

        this.broadcast("onDealerChanged", {
            dealer: this._dealerIndex,
            dealerLZ: this._dealerLZ
        });
    },


    /******************************************************************
     * 消息处理
     ******************************************************************/
    handleGift: function (player, msg, callback) {
        if (isNaN(msg.targetIndex)) {
            callback({code: Code.ARGS_INVALID});
            return;
        }

        var gameConfig = this.getGameConfig();
        var giftType = msg.type;
        var giftConfig = gameConfig.Gift[giftType];
        if (!giftConfig) {
            callback({code: Code.ARGS_VALUE_WRONG});
            return;
        }

        var targetIndex = parseInt(msg.targetIndex);
        var targetPlayer = this.getPlayerByIndex(targetIndex);
        if (!targetPlayer) {
            callback({code: SubCode.INDEX_INVALID});
            return;
        }

        if (!player.checkResource(giftConfig.costs)) {
            callback({code: Code.LACK_OF_COIN});
            return;
        }

        this.broadcast("onPlayerGift", {
            playerIndex: player.getIndex(),
            targetIndex: targetIndex,
            type: giftType
        });
        callback();

        player.costResourceSync(giftConfig.costs);
        // targetPlayer.addResourceSync(giftConfig.harvest);
    },
    //
    handleShaiZiAndCards:function(player, msg, callback)
    {
        if(this.yaoshaizi == 0) {
            var shaiziandcard = {
                num1: 0,
                num2: 0,
                num3: 0,
                num4: 0,
                secondindex:0,
                card: 0,
            };
            this.yaoshaizi += 1;
            shaiziandcard.num1 = ExNumber.rand(6) + 1;
            shaiziandcard.num2 = ExNumber.rand(6) + 1;
            this._shaiziN = shaiziandcard.num1 + shaiziandcard.num2;
            shaiziandcard.num3 = ExNumber.rand(6) + 1;
            shaiziandcard.num4 = ExNumber.rand(6) + 1;
            this._shaiziM = shaiziandcard.num3 + shaiziandcard.num4;
            shaiziandcard.card = this.getRandomCard();
            //shaiziandcard.card = 3;
            var subconfig = this.getSubConfig();
            var num = this._shaiziN % subconfig.roomPlayerNum;
            this.SecondPlayer = this.getDealerIndex();
            for(var i = 0; i < num; i++){
                this.SecondPlayer = this.getNextPlaying(this.SecondPlayer);
            }
            shaiziandcard.secondindex = this.SecondPlayer;

            this.baoCard = shaiziandcard.card;
            this.yNum1 = shaiziandcard.num1;
            this.yNum2 = shaiziandcard.num2;
            this.yNum3 = shaiziandcard.num3;
            this.yNum4 = shaiziandcard.num4;
            this.broadcast("onyYaoShaiZi", shaiziandcard);
            this.initPlayersHandCards();
        }else{
            if(this.yaoshaizi == 1){
                this.yaoshaizi += 1;
            }
            this.broadcast("onyYaoShaiZi", {});
            this.startPlay();
        }
        callback({});
       // this.onAfterStartNewRound();
    },


    /******************************************************************
     * 功能接口
     ******************************************************************/

    /**
     * 结算玩家是否听牌
     * @param player
     * @private
     */
    _settlementPlayerTing: function(player) {
        //已听牌玩家不用再检测
        if (player.isRoundTing()) {
            return;
        }

        // 对未胡牌的玩家检查是否听牌
        var tings = player.checkTing();
        var pattern = Const.Pattern.NONE;
        var patternScore = 0;
        for (var i = 0; i < tings.length; ++i) {
            var ting = tings[i];

            /*
            var appearedNum = 0;
            this.enumPlayers(function(eIndex, ePlayer) {
               if (ePlayer.isPlaying()) {
                   appearedNum += ePlayer.getAppearedCardNum(ting.card);
               }
            });
            logger.debug("room=%d index=%d _settlementPlayerTing ting=%j appearedNum=%d handNum=%d", this.rid(), player.getIndex(), ting, appearedNum, player.getHandCardNum(ting.card));
            if (appearedNum + player.getHandCardNum(ting.card) >= 4) { // 死叫
                continue;
            }
            */

            var score = Const.PatternScore[ting.pattern];
            if (score > patternScore) {
                pattern = ting.pattern;
                patternScore = score;
            }
        }

        player.setRoundPattern(pattern, 0);
    },
    //随机获取一张牌
    getRandomCard:function()
    {
        var index = ExNumber.rand(this._publicCards.cards.length - 1);
        var card = this._publicCards.cards[index];

        return card;
    },
    //获取玩家宝牌数量
    getBaoCardNum:function(player)
    {
        return player._handCards.getCardNum(this.baoCard);
    },
    // 给当前玩家发一张牌,摸到翻牌结算流局

    onBeforeNewCard:function(){
        if(this._publicCards.getRemainNum() <= this._shaiziM + this._shaiziN + 1){
            this.settlementCurRound(0);
        }
    },

});